<?php

class UploadUtil
{
	/**
	 * Context 
	 *
	*@var Context
	*/
	protected $_context;
	
	/**
	 * Atualiza as propriedades do arquivo com as informações do arquivo carregado.
	 *
	 * @var UploadedFileProperties
	 */
	protected $_properties;
	
	/**
	 * Novo nome do arquivo carregado.
	 *
	 * @var string
	 */
	protected $_name;

	/**
	 * Diretório onde o arquivo será alocado.
	 *
	 * @var string
	 */
	protected $_targetdir = '';

	/**
	 * Substitui o arquivo se já existir.
	 *
	 * @var boll
	 */
	protected $_replace = true;
	
	/**
	 * Se encontra o arquivo ou não.
	 *
	 * @var boll
	 */
	protected $_findfile = false;
	
	/**
	 * Peocessador de arquivo.
	 *
	 * @var UploadFilenameProcessor
	 */
	protected $_file;
	
	/**
	 * Permitir acentuação
	 *
	 * @var bool
	 */
	public $allowSpecialChars = true;
	
	/**
	 * Construtor.
	 *
	 * @param string $fieldname
	 * @param UploadFilenameProcessor $file
	 * @param bool $replace
	 */
	public function UploadUtil($fieldname, $file, $replace = true)
	{
		if(empty($fieldname))
		{
			throw new UploadUtilExecption("O campo nome no arquivo a ser carregado está vazio.");
		}
		elseif(get_class($file) != 'UploadFilenameProcessor')
		{
			throw new UploadUtilExecption("O processador do arquivo deve do tipo UploadFilenameProcessor.");
		}
		$this->_context = Context::getInstance();
		$this->_replace = $replace;
		$this->_file = $file;
		$this->_properties = $this->_context->getUploadedFile($fieldname);
		
		$this->_findfile = true;
		$this->_name = $this->_properties->name;
		
		if(empty($this->_name))
		{
			throw new UploadUtilExecption("O campo de carregamento \"$fieldname\" não foi encontrado ou está vazio.");
		}
	}
	
	/**
	 * Recebe nome do arquivo enviado pelo formulário.
	 *
	 * @return string
	 */
	public function getUploadedFileName()
	{
		return $this->_name;
	}
		
	/**
	 * Inicia a trasação do arquivo carregado.
	 *
	 * @return string
	 */
	public function saveUploadedFile()
	{
		$size = round($this->_properties->size / 1024);
		$avaliable = substr(get_cfg_var("upload_max_filesize"), 0, -1) * 1024;
		if ($size > $avaliable) 
		{
			throw new UploadUtilExecption("Execedeu o tamanho do arquivo.");
		}
		
		if ($this->_file->Extension() == '.*') 
		{
			$uploadedFileParts = pathinfo($this->_name);
			$this->_file->setExtension($uploadedFileParts['extension']);
		}
		if ($this->_file->ToString() == '*') 
		{
			$uploadedFileParts = pathinfo($this->_name);
			$name = $this->trimName(basename($uploadedFileParts["basename"], '.' . $uploadedFileParts['extension']));
			if (!$this->allowSpecialChars)
			{
				$name = preg_replace('/í|ì|î|ï/i', 'i', $name);
				$name = preg_replace('/Í|Ì|Î|Ï/i', 'I', $name);
				$name = preg_replace('/é|è|ê|ë/i', 'e', $name);
				$name = preg_replace('/É|È|Ê|Ë/i', 'E', $name);
				$name = preg_replace('/ã|â|á|à|ä/i', 'a', $name);
				$name = preg_replace('/Ã|Â|Á|À|Ä/i', 'A', $name);
				$name = preg_replace('/ó|ò|õ|ö|ô/i', 'o', $name);
				$name = preg_replace('/Ó|Ò|Õ|Ö|Ô/i', 'O', $name);
				$name = preg_replace('/ç/i', 'c', $name);
				$name = preg_replace('/Ç/i', 'C', $name);
				$name = preg_replace('/ñ/i', 'n', $name);
				$name = preg_replace('/Ñ/i', 'N', $name);
			}
			$this->_file->setName($name);
		}
		else 
		{
			$this->_file->setName($this->trimName($this->_file->ToString()));
		}
		

		$fileNameAndPath = $this->_file->FullQualifiedNameAndPath();
		
		
		if ($this->_replace) 
		{
			try 
			{
				FileUtil::DeleteFile($this->_file);
			}
			catch (UploadUtilExecption $ex){}
		}
		elseif (FileUtil::Exists($fileNameAndPath))
		{
			$fileNameAndPath = $this->getAValidName();
		}
		
		FileUtil::ForceDirectories($this->_file->PathSuggested());
		
		if(!move_uploaded_file($this->_properties->tmp_name, $fileNameAndPath) && @chmod($fileNameAndPath, 0777))
		{
			throw new UploadUtilExecption("Nao é possível mover o arquivo carregado.");
		}

		$this->_name = $fileNameAndPath;
		return $this->_file->BaseFullFileNameAndPath($fileNameAndPath);
	}
	
	/**
	 * Procura por espaços no nome e substitui por "_" .
	 *
	 * @param string $name
	 * @return string
	 */
	protected function trimName($name)
	{
		return str_replace(' ', '_', $name);
	}
	
	/**
	 * Encontra um nome válido para o arquivo.
	 *
	 * @return string
	 */
	protected function getAValidName()
	{
		$path = $this->_file->PathSuggested();
		$extension = $this->_file->Extension();
		$singleName = basename($this->_file->FullQualifiedName(), $extension);
		$cont = 1;
		do 
		{
			$testpath = $path . $singleName . "_$cont" . $extension;
			$cont++;
		}
		while (FileUtil::Exists($testpath));
		return $testpath;
	}
}
?>